package com.atguigu.tingshu.user.api;


import cn.binarywang.wx.miniapp.api.WxMaService;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.login.TSLogin;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.user.UserInfo;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Tag(name = "微信授权登录接口")
@RestController
@RequestMapping("/api/user/wxLogin")
@Slf4j
public class WxLoginApiController {

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private WxMaService wxMaService;

    @Autowired
    private RabbitService rabbitService;

    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 微信登录
     * @param code
     * @return
     */
    //http://192.168.200.1/api/user/wxLogin/wxLogin/0a3QvjFa10eSTH0XrzFa1yrcxk0QvjFr
    @Operation(summary = "微信登录")
    @GetMapping("/wxLogin/{code}")
    public Result wxLogin(@PathVariable String code) {
        //调用服务层方法
        String openId=null;
        //使用code（小程序登录凭证）获取用户的唯一标识符（OpenID），并将结果赋值给openId变量。
        try {
            openId=wxMaService.jsCode2SessionInfo(code).getOpenid();
        } catch (WxErrorException e) {
            //抛出自定义异常 SERVICE_ERROR:服务异常
            throw new GuiguException(ResultCodeEnum.SERVICE_ERROR);
        }
        //根据openid查询用户信息
        UserInfo userInfo=userInfoService.getOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getWxOpenId,openId));
        //判断用户是否存在
        if(null==userInfo){
            //用户不存在，创建用户
            userInfo=new UserInfo();
            //设置用户openId
            userInfo.setWxOpenId(openId);
            //设置用户昵称
            //将听友加当前系统时间戳作为昵称确保昵称的唯一性
            userInfo.setNickname("听友"+System.currentTimeMillis());
            //设置默认头像
            userInfo.setAvatarUrl("https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
            //todo(未写) 设置用户vip身份信息 is_vip 默认0 不属于vip 1属于vip
            //保存用户信息
            userInfoService.save(userInfo);
            //通过rabbitmq发送消息初始化金额来促进用户消费；account 远程调用
            rabbitService.sendMessage(MqConst.EXCHANGE_USER,MqConst.ROUTING_USER_REGISTER,userInfo.getId());
        }
        //现在无论是之前就有用户openid还是现在新用户openid都会在此之后生成一个UUID作为token保存在缓存中
        //生成一个UUID作为token
        String token= UUID.randomUUID().toString().replaceAll("-","");
        //将用户信息+token保存到redis缓存中
        String loginKey= RedisConstant.USER_LOGIN_KEY_PREFIX+token;
        //设置key=loginKey
        // vlaue=userInfo
        // 过期时间
        this.redisTemplate.opsForValue().set(loginKey,userInfo,RedisConstant.USER_LOGIN_KEY_TIMEOUT, TimeUnit.SECONDS);
        //将token返回给前端
        HashMap<String, Object> map=new HashMap<>();
        //给要给前端的map设置token
        //key=token要与前端一致
        map.put("token",token);
        //返回数据
        return Result.ok(map);
    }


    /**
     * 通过用户Id获取用户信息
     * @return
     */
    //http://192.168.200.1/api/user/wxLogin/getUserInfo
    @TSLogin
    @Operation(summary = "获取用户信息")
    @GetMapping("/getUserInfo")
    public Result getUserInfo(){
        //获取用户ID
        Long userId = AuthContextHolder.getUserId();
        //调用服务层方法
        UserInfoVo userInfoVo= this.userInfoService.getUserInfoVo(userId);
        //返回数据
        return Result.ok(userInfoVo);
    }

    @TSLogin
    @Operation(summary = "修改用户信息")
    @PostMapping("/updateUser")
    public Result updateUser(@RequestBody UserInfoVo userInfoVo){
        //  获取用户Id -- 以下代码能否获取到用户Id
        Long userId = AuthContextHolder.getUserId();
        //  直接修改！
        UserInfo userInfo = new UserInfo();
        userInfo.setId(userId);
        userInfo.setAvatarUrl(userInfoVo.getAvatarUrl());
        userInfo.setNickname(userInfoVo.getNickname());
        this.userInfoService.updateById(userInfo);
        //  返回数据
        return Result.ok();
    }
}
